package com.mixsmart.commonweb.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.mixsmart.commonweb.bean.entity.TCOperateFlag;
import com.mixsmart.commonweb.bean.entity.TCUrlResOpFlag;
import com.mixsmart.commonweb.bean.entity.TCUrlResource;
import com.mixsmart.commonweb.enums.UrlResourceType;
import com.mixsmart.commonweb.service.IRoleService;
import com.mixsmart.commonweb.service.IRoleUrlResService;
import com.mixsmart.commonweb.service.IUrlResourceService;
import com.mixsmart.enums.YesNoType;
import com.mixsmart.spellsql.utils.Cnd;
import com.mixsmart.spellsql.utils.Exp;
import com.mixsmart.utils.CollectionUtils;
import com.mixsmart.utils.StringUtils;

/**
 * URL资源服务--实现类
 * @author lmq
 * @version 1.0
 * @since JDK版本大于等于1.6
 * 2016年2月1日
 */
@Service
public class UrlResourceService extends WebMgrService<TCUrlResource> implements IUrlResourceService {

	@Autowired
	private OperateFlagService operateFlagServ;
	@Autowired
	private UrlResOpFlagService resOpFlagServ;
	@Autowired
	private IRoleUrlResService roleUrlResServ;
	@Autowired
	private IRoleService roleServ;
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED,readOnly=false)
	public boolean save(TCUrlResource t) {
		boolean is = false;
		if(null != t) {
			if(super.save(t)) {
				if(CollectionUtils.isNotEmpty(t.getResOpFlags())) {
					this.urlResOpFlagRelate(t, t.getResOpFlags());
					super.saveObj((ArrayList<TCUrlResOpFlag>)t.getResOpFlags());
				}
				//获取超级管理员角色ID
				String superRoleId = roleServ.getSuperRoleId();
				if(StringUtils.isNotEmpty(superRoleId)) {
					roleUrlResServ.save(superRoleId, t);
				}
				is = true;
			}
		}
		return is;
	}
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED,readOnly=false)
	public boolean update(TCUrlResource t) {
		boolean is = false;
		if(null != t) {
			if(super.update(t)) {
				List<TCUrlResOpFlag> oldResOpFlags = resOpFlagServ.finds(Cnd.where(Exp.eq("urlResId", t.getId())));
				if(CollectionUtils.isNotEmpty(t.getResOpFlags())) {
					//如果该资源中没有添加过操作标志，则全新添加
					if(CollectionUtils.isEmpty(oldResOpFlags)) {
						this.urlResOpFlagRelate(t, t.getResOpFlags());
						if(CollectionUtils.isNotEmpty(t.getResOpFlags())) {
							super.saveObj((ArrayList<TCUrlResOpFlag>)t.getResOpFlags());
						}
					} else { 
						//如果该资源中以前添加操作标志，则更新(有的更新，没有的删除，新增的保存)
						this.updateResOpFlag(t, oldResOpFlags, t.getResOpFlags());
					}
				} else if(CollectionUtils.isNotEmpty(oldResOpFlags)){ 
					//如果以前添加，现在没有，则删除
					this.deleteNotExist(oldResOpFlags);
				}
				//获取超级管理员角色ID
				String superRoleId = roleServ.getSuperRoleId();
				if(StringUtils.isNotEmpty(superRoleId)) {
					roleUrlResServ.update(superRoleId, t);
				}
				is = true;
			}
		}
		return is;
	}
	
	/**
	 * 资源与操作标识关联
	 * @param urlRes URL资源对象
	 * @param resOpFlags 资源操作标识关联对象集合
	 * @throws MixSmartException
	 */
	private void urlResOpFlagRelate(TCUrlResource urlRes,List<TCUrlResOpFlag> resOpFlags) {
		List<Integer> removes = null;
		int index = 0;
		for(TCUrlResOpFlag resOpFlag : resOpFlags) {
			if(StringUtils.isNotEmpty(resOpFlag.getOpFlagId())) {
				if(StringUtils.isNotEmpty(resOpFlag.getViewUrl())) {
					this.opFlagUrlResRelate(urlRes, resOpFlag, "页面", true);
				}
				if(StringUtils.isNotEmpty(resOpFlag.getPostUrl())){
					this.opFlagUrlResRelate(urlRes, resOpFlag, "数据地址", false);
				}//if
				resOpFlag.setUrlResId(urlRes.getId());
			} else {
				if(null == removes) {
					removes = new ArrayList<Integer>();
				}
				removes.add(index);
			}
			index++;
		}//for
		if(null != removes) {
			int delCount = 0;
			for (Integer i : removes) {
				resOpFlags.remove(i.intValue()-delCount);
				delCount++;
			}
		}//if
	}
	
	/**
	 * 操作标识与URL资源关联
	 * @param urlRes URL资源对象
	 * @param resOpFlag 资源操作标识关联对象
	 * @param resName 资源名称
	 * @param isView 是否是页面URL
	 * @throws MixSmartException
	 */
	private void opFlagUrlResRelate(TCUrlResource urlRes, TCUrlResOpFlag resOpFlag,
			 String resName, boolean isView) {
		TCOperateFlag operateFlag = operateFlagServ.find(resOpFlag.getOpFlagId());
		if(null != operateFlag) {
			resName = urlRes.getName()+operateFlag.getName()+resName;
			TCUrlResource opUrlRes = null;
			if(isView) 
				opUrlRes = new TCUrlResource(resName, resOpFlag.getViewUrl(),YesNoType.YES.getIndex(),UrlResourceType.OP_URL_RESOURCE.getValue());
			else 
				opUrlRes = new TCUrlResource(resName, resOpFlag.getPostUrl(),YesNoType.YES.getIndex(),UrlResourceType.OP_URL_RESOURCE.getValue());
			if(super.save(opUrlRes)) {
				if(isView)
					resOpFlag.setViewUrlResId(opUrlRes.getId());
				else 
					resOpFlag.setPostUrlResId(opUrlRes.getId());
			}
		}
	}
	
	/**
	 * 更新资源与操作标志的数据;
	 * <p>更新的条件是：新关联关系中与旧的关联关系对比；两者的交集更新；两者的差集：新的差集保存；旧的差集删除</p>
	 * @param urlRes 资源对象
	 * @param oldResOpFlags 以前资源与操作标志关联数据
	 * @param newResOpFlags 现资源与操作标志关联数据
	 */
	private void updateResOpFlag(TCUrlResource urlRes, List<TCUrlResOpFlag> oldResOpFlags,List<TCUrlResOpFlag> newResOpFlags) {
		List<TCUrlResOpFlag> intersects = getIntersection(oldResOpFlags, newResOpFlags);
		newResOpFlags.removeAll(intersects);
		oldResOpFlags.removeAll(intersects);
		//更新
		this.updateIntersection(intersects);
		//新增
		if(CollectionUtils.isNotEmpty(newResOpFlags)) {
			this.urlResOpFlagRelate(urlRes, newResOpFlags);
			if(CollectionUtils.isNotEmpty(newResOpFlags)) 
				super.saveObj((ArrayList<TCUrlResOpFlag>)newResOpFlags);
		}
		//删除老的数据
		if(CollectionUtils.isNotEmpty(oldResOpFlags)) {
			this.deleteNotExist(oldResOpFlags);
		}
	}
	
	/**
	 * 获取交集
	 * @param oldResOpFlags
	 * @param newResOpFlags
	 * @return
	 */
	private List<TCUrlResOpFlag> getIntersection(List<TCUrlResOpFlag> oldResOpFlags,List<TCUrlResOpFlag> newResOpFlags) {
		List<TCUrlResOpFlag> intersects = new ArrayList<TCUrlResOpFlag>();
		for (TCUrlResOpFlag newResOpFlag : newResOpFlags) {
			for (TCUrlResOpFlag oldResOpFlag : oldResOpFlags) {
				if(newResOpFlag.getId().equals(oldResOpFlag.getId())) {
					intersects.add(newResOpFlag);
					break;
				}
			}
		}
		return intersects;
	}
	
	/**
	 * 更新交集中的数据
	 * @param intersects 交集数据集合
	 * @throws MixSmartException
	 */
	private void updateIntersection(List<TCUrlResOpFlag> intersects) {
		ArrayList<TCUrlResource> urlResUpdates = new ArrayList<TCUrlResource>();
		List<String> deleteIds = new ArrayList<String>();
		for (TCUrlResOpFlag resOpFlag : intersects) {
			if(StringUtils.isNotEmpty(resOpFlag.getPostUrl())) {
				TCUrlResource urlRes = super.find(resOpFlag.getPostUrlResId());
				urlRes.setUrl(resOpFlag.getPostUrl());
				urlResUpdates.add(urlRes);
			} else {
				if(StringUtils.isNotEmpty(resOpFlag.getPostUrlResId())) {
					deleteIds.add(resOpFlag.getPostUrlResId());
				}
			}
			if(StringUtils.isNotEmpty(resOpFlag.getViewUrl())) {
				TCUrlResource urlRes = super.find(resOpFlag.getViewUrlResId());
				urlRes.setUrl(resOpFlag.getViewUrl());
				urlResUpdates.add(urlRes);
			} else {
				if(StringUtils.isNotEmpty(resOpFlag.getViewUrlResId())) {
					deleteIds.add(resOpFlag.getViewUrlResId());
				}
			}
		}
		super.update(urlResUpdates);
		String[] idArray = new String[deleteIds.size()];
		deleteIds.toArray(idArray);
		super.delete(idArray);
	}
	
	/**
	 * 删除不存在的数据
	 * @param resOpFlags 资源操作数据
	 * @throws MixSmartException
	 */
	private void deleteNotExist(List<TCUrlResOpFlag> resOpFlags) {
		//获取对应的资源ID
		List<String> idList = new ArrayList<String>(resOpFlags.size()*2);
		for (int i = 0; i < resOpFlags.size(); i++) {
			if(StringUtils.isNotEmpty(resOpFlags.get(i).getPostUrlResId())) {
				idList.add(resOpFlags.get(i).getPostUrlResId());
			}
			if(StringUtils.isNotEmpty(resOpFlags.get(i).getViewUrlResId())) {
				idList.add(resOpFlags.get(i).getViewUrlResId());
			}
		}
		//删除资源与操作标识的关联数据
		resOpFlagServ.delete((ArrayList<TCUrlResOpFlag>)resOpFlags);
		String[] idArray = new String[idList.size()];
		idList.toArray(idArray);
		//删除操作标识对应的资源
		super.delete(idArray);
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
	public boolean delete(String[] ids) {
		boolean is = false;
		HashMap<String, Object> params = new HashMap<String, Object>(1);
		params.put("ids", ids);
		logger.info("正在级联删除资源信息...");
		getExecuteServ().executes("del_cascade_urlRes", params);
		logger.info("级联删除资源信息[成功]...");
		is = true;
		return is;
	}
}
